home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n05.arc / 2BOTH.ARC / FCOMMON.C < prev    next >
Text File  |  1991-02-13  |  10KB  |  387 lines

  1. /* PROJECT....:  2FILE.C and 2FLOPPY.C
  2. ** FILE.......:  fcommon.c
  3. ** VERSION....:  1.0 (Turbo C++ 1.0 & MSC 5.0)
  4. ** AUTHOR.....:  Stephen D. Cooper
  5. ** NOTICE.....:  Copyright 1990 ZIFF Communications Co.
  6. **
  7. ** NOTES......:  This file contains those routines that are used by
  8. **         both 2FILE.C and 2FLOPPY.C.
  9. **
  10. ** COMPILE....:     Using Turbo C:
  11. **         2file.exe   ==> tcc -D_2FILE_C_ -O 2file.c fcommon.c
  12. **         2floppy.exe ==> tcc -mc -O 2floppy.c fcommon.c
  13. **
  14. **         Using MSC:
  15. **         2file.exe   ==> cl /D_2FILE_C_ 2file.c fcommon.c
  16. **         2floppy.exe ==> cl /AC 2floppy.c fcommon.c
  17. */
  18.  
  19. /********************************************************************
  20. **        INCLUDE FILES                           **
  21. ********************************************************************/
  22.  
  23. #define ERROR_FILE
  24.  
  25. #include <conio.h>
  26. #include <ctype.h>
  27. #include <dos.h>
  28. #include <signal.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "compiler.h"
  33. #include "fcommon.h"
  34.  
  35. #if defined _2FILE_C_
  36. #include "2fil_err.h"
  37. #else
  38. #include "2flo_err.h"
  39. #endif
  40.  
  41. /********************************************************************
  42. *********************************************************************
  43. **        CODE STARTS                             **
  44. *********************************************************************
  45. ********************************************************************/
  46.  
  47. /*********************************************************************
  48. ** FUNCTION check_filename()                                    **
  49. *********************************************************************/
  50.  
  51. int check_filename(char *destname, char *given, DISKSTATS *dstats)
  52. {
  53.     char drive[MAXDRIVE],
  54.          dir[MAXDIR],
  55.          name[MAXFILE],
  56.          ext[MAXEXT];
  57.  
  58.     /*
  59.     ** Parse the file name
  60.     */
  61.     SPLITPATH(strupr(given), drive, dir, name, ext);
  62.  
  63.     /*
  64.     ** Check drive letter -- If not given, default is current drive
  65.     */
  66.     if(!isalpha(*drive))
  67.     {
  68. #if defined(TURBO_C)
  69.         drive[0] = getdisk() + 'A';
  70. #else
  71.         _dos_getdrive(drive);
  72.         drive[0] += 'A' - 1;
  73. #endif
  74.         drive[1] = ':';
  75.         drive[2] = '\0';
  76.     }
  77.     if(drive[0] - 'A' == dstats->drivenum)
  78.         return(ERR_SAME_DRIVE);
  79.  
  80.     /*
  81.     ** Check for a file name -- If not given, return an error
  82.     ** NOTE:  This does not check for a valid file name --
  83.     **        that will be found when we try to open the file
  84.     */
  85.     if(*name == '\0')
  86.         return(ERR_NO_FILENAME);
  87.  
  88.     /*
  89.     ** Check for an extension -- If not given, use .FLP as default
  90.     */
  91.     if(*ext == '\0')
  92.         strcpy(ext, ".FLP");
  93.  
  94.     /*
  95.     ** Put it all back together again
  96.     */
  97.     MAKEPATH(destname, drive, dir, name, ext);
  98.  
  99.     return(ERR_NO_ERRORS);
  100. }
  101.  
  102. /*********************************************************************
  103. ** FUNCTION check_numargs()                            **
  104. *********************************************************************/
  105.  
  106. int check_numargs(int argc, int minargs, int maxargs)
  107. {
  108.     if(argc < minargs)
  109.         return(ERR_TOO_FEW_ARGS);
  110.     else if(argc > maxargs)
  111.         return(ERR_TOO_MANY_ARGS);
  112.     else
  113.         return(ERR_NO_ERRORS);
  114. }
  115.  
  116. /*********************************************************************
  117. ** FUNCTION continue_yn()                            **
  118. *********************************************************************/
  119.  
  120. int continue_yn(void)
  121. {
  122.     cputs("Continue (Y/N)? ");
  123.  
  124.     return(getyn());
  125. }
  126.  
  127. /********************************************************************
  128. ** FUNCTION....:  ctrlbrk_handler(void)                   **
  129. **                                   **
  130. ** RETURNS.....:  Nothing                       **
  131. **                                   **
  132. ** CALLS.......:  getyn()                       **
  133. **          err_exit()                       **
  134. **                                   **
  135. ** NOTES.......:  ctrlbrk_handler() is the program's Ctrl-Break       **
  136. **          handler.  If the user presses Ctrl-Break, this   **
  137. **          routine displays a message asking the user to    **
  138. **          confirm the program exit.  If yes, err_exit() is **
  139. **          called with ERR_USER_ABORT, else the program       **
  140. **          resumes operation.                   **
  141. ********************************************************************/
  142.  
  143. void ctrlbrk_handler(void)
  144. {
  145.     /*
  146.     ** Turn off the Ctrl-Break handler
  147.     ** and ignore any further Ctrl-Breaks
  148.     */
  149.     signal(SIGINT, SIG_IGN);
  150.  
  151.     /*
  152.     ** Ask the user to confirm the Ctrl-Break.
  153.     ** Exit if confirmed, return if not.
  154.     */
  155.     printf("\nCtrl-Break was pressed -- "
  156.            "Do you wish to exit the program (Y/N)? ");
  157.  
  158.     if(getyn() == 'Y')
  159.     {
  160.         printf("\n\n");
  161.         err_exit(ERR_USER_ABORT);
  162.     }
  163.  
  164.     printf("\n\n");
  165.     signal(SIGINT, ctrlbrk_handler);
  166. }
  167.  
  168. /********************************************************************
  169. ** FUNCTION....:  err_exit(int errcode)                   **
  170. **                                   **
  171. ** PARAMETERS..:  int errcode - Error code that points to the       **
  172. **                message to display to the user       **
  173. **                                   **
  174. ** RETURNS.....:  Nothing                       **
  175. **                                   **
  176. ** NOTES.......:  err_exit() displays an error message, cleans-up  **
  177. **          if needed, and exits to DOS with an ERRORLEVEL   **
  178. ********************************************************************/
  179.  
  180. void err_exit(int errcode)
  181. {
  182.     if(errcode != ERR_USER_ABORT)
  183.         printf("ERROR(%d):  ", errcode);
  184.  
  185.     printf("%s.\n\n", errmsg[errcode]);
  186.  
  187.     if(prg_status == HARDERR_CRITICAL)
  188.     {
  189.         free(read_buff);
  190.         fcloseall();
  191. #if defined(_2FILE_C_)
  192.         remove(filename);
  193. #endif
  194.     }
  195.  
  196.     exit(errcode);
  197. }
  198.  
  199. /*********************************************************************
  200. ** FUNCTION floppyletter_2_number()                    **
  201. *********************************************************************/
  202.  
  203. int floppyletter_2_number(unsigned *drivenum, char *drive)
  204. {
  205.     *drive = toupper(*drive);
  206.  
  207.     if(*drive == 'A' || *drive == 'B')
  208.         if(*(drive + 1) == ':' && *(drive + 2) == '\0')
  209.         {
  210.             *drivenum = *drive - 'A';
  211.             return(ERR_NO_ERRORS);
  212.         }
  213.  
  214.     return(ERR_FLOPPY_LETTER);
  215. }
  216.  
  217. /********************************************************************
  218. ** FUNCTION....:  getyn(void)                         **
  219. **                                   **
  220. ** RETURNS.....:  'Y' = user pressed 'Y'               **
  221. **          'N' = user pressed 'N'               **
  222. **                                   **
  223. ** NOTES.......:  getyn() waits for the user to press either 'Y'   **
  224. **          or 'N' (either upper or lower case).           **
  225. **          NOTE:  The user keypress is echoed.           **
  226. ********************************************************************/
  227.  
  228. int getyn(void)
  229. {
  230.     int retval = 'A';
  231.  
  232.     while(retval != 'Y' && retval != 'N')
  233.         retval = toupper(getche());
  234.  
  235.     return(retval);
  236. }
  237.  
  238. /********************************************************************
  239. ** FUNCTION....:  harderr_handler()                   **
  240. **                                   **
  241. ** RETURNS.....:                             **
  242. **                                   **
  243. ** NOTES.......:  I know that this function is VERY hard to read,  **
  244. **          but it must be this way in order for it to work  **
  245. **          with both Turbo C and MSC.  To get the        **
  246. **          definition of the UPPER CASE words, please look  **
  247. **          at fcommon.h.                       **
  248. ********************************************************************/
  249.  
  250. #pragma argsused
  251. HARDERR_HANDLER
  252. {
  253.     char buff[2];
  254.  
  255.     if(prg_status == HARDERR_NON_CRITICAL)
  256.     {
  257.         if((ax & 0x8000) == 0)        /* bit 15 -> 0 = disk */
  258.         {
  259.             buff[0] = (ax & 0x00FF) + 'A';    /* disk drive letter */
  260.             buff[1] = '\0';
  261.  
  262.             cputs("A disk error has occurred.  Please make sure ");
  263.             cputs("that there\r\n");
  264.             cputs("is a disk in drive ");
  265.             cputs(buff);
  266.             cputs(": and that the drive door is closed.\r\n\n");
  267.  
  268.             if(continue_yn() == 'N')
  269.                 harderr_status = HARDERR_ABORT;
  270.             else
  271.                 harderr_status = HARDERR_RETRY;
  272.         }
  273.         else
  274.         {
  275.             cputs("A non-disk critical hardware error has ");
  276.             cputs("occurred.\r\n");
  277.             cputs("Please make sure you're computer is working ");
  278.             cputs("properly and try again.\r\n\n");
  279.  
  280.             harderr_status = HARDERR_ABORT;
  281.         }
  282.     }
  283.     else
  284.     {
  285.         cputs("\r\n\nAn unrecoverable hardware error has ");
  286.         cputs("occurred.  Please try again making sure\r\n");
  287.         cputs("that the source drive contains the source disk, ");
  288.         cputs("that the destination drive\r\n");
  289.         cputs("contains a formatted disk, and that all drive ");
  290.         cputs("doors are closed.");
  291.  
  292.         harderr_status = HARDERR_ABORT;
  293.     }
  294.     cputs("\r\n\n");
  295.  
  296.     HARDRETN(HARDERR_RET_CODE);
  297.  
  298. #if defined(TURBO_C)
  299.     return(HARDERR_IGNORE);
  300. #endif
  301. }
  302.  
  303. /********************************************************************
  304. ** FUNCTION..:  read_sectors()                      **
  305. ********************************************************************/
  306.  
  307. int read_sectors(int track, int head, char *buff, DISKSTATS *dstats)
  308. {
  309.     int retval;
  310.     unsigned char *newbuff;
  311.     union REGS inregs, outregs;
  312.  
  313.     /*
  314.     ** Set up registers for call
  315.     */
  316.     inregs.h.ah = BIOSFUNC_READ_SECTOR;
  317.     if(dstats->numsectors > 9)
  318.         inregs.h.al = 9;
  319.     else
  320.         inregs.h.al = dstats->numsectors;
  321.     inregs.h.ch = track;
  322.     inregs.h.cl = 1;
  323.     inregs.h.dh = head;
  324.     inregs.h.dl = dstats->drivenum;
  325.     inregs.x.bx = FP_OFF((char far *)buff);
  326.  
  327.     retval = sector_read(&inregs, &outregs, buff, dstats);
  328.     if(retval != 0)
  329.         return(retval);
  330.  
  331.     if(dstats->numsectors > 9)
  332.     {
  333.         inregs.h.al = dstats->numsectors - 9;
  334.         inregs.h.cl = 10;
  335.         newbuff = buff + (9 * dstats->sectorsize);
  336.         inregs.x.bx = FP_OFF((char far *)newbuff);
  337.         retval = sector_read(&inregs, &outregs, newbuff, dstats);
  338.     }
  339.     return(retval);
  340. }
  341.  
  342. /********************************************************************
  343. ** FUNCTION..:  reset_drive()                       **
  344. ********************************************************************/
  345.  
  346. int reset_drive(int drivenumber)
  347. {
  348.     union REGS regs;
  349.  
  350.     regs.h.ah = BIOSFUNC_RESET;
  351.     regs.h.dl = drivenumber;
  352.  
  353.     int86(BIOS_DISK, ®s, ®s);
  354.  
  355.     return(regs.h.ah == 0 ? 0 : ERR_RESETTING_DRIVE);
  356. }
  357.  
  358. /********************************************************************
  359. ** FUNCTION..:  sector_read()                      **
  360. ********************************************************************/
  361.  
  362. int sector_read(union REGS *inregs, union REGS *outregs, char *buff,
  363.                 DISKSTATS *dstats)
  364. {
  365.     int try_cntr = 3;
  366.     struct SREGS sregs;
  367.  
  368.     /*
  369.     ** Try 3 times if not succesful
  370.     */
  371.     do
  372.     {
  373.         sregs.es = FP_SEG((char far *)buff);
  374.         int86x(BIOS_DISK, inregs, outregs, &sregs);
  375.         if(outregs->h.ah != 0)
  376.             reset_drive(dstats->drivenum);
  377.     } while(outregs->h.ah != 0 && --try_cntr > 0);
  378.  
  379.     return(outregs->h.ah == 0 ? 0 : ERR_READING_FLOPPY);
  380. }
  381.  
  382. /******************************
  383. *******************************
  384. **** END OF FILE fcommon.c ****
  385. *******************************
  386. ******************************/
  387.